package com.rightrule.rule.executor.rule;

import com.alibaba.fastjson.JSONObject;
import com.googlecode.aviator.exception.ExpressionRuntimeException;
import com.rightrule.rule.compile.CompilableInstance;
import com.rightrule.rule.constans.CommonConstant;
import com.rightrule.rule.executor.RuntimeContext;
import com.rightrule.rule.response.BaseExecutionResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * 表达式规则
 */
@Data
@Slf4j
public class ExpressionRule extends BaseRule {

    /**
     * 要执行的表达式编译对象
     */
    private CompilableInstance rcRiskCodeCompiledInstance;


    /**
     * 执行决策方法
     *
     * @param context
     * @param varibleMap
     * @return
     */
    @Override
    BaseExecutionResponse executeAndGet(RuntimeContext context, Map<String, Object> varibleMap) {

        BaseExecutionResponse executionResponse = new BaseExecutionResponse();

        CompilableInstance compilableInstance = getCompilableInstance();
        String exeResultData = "{}";

        // 如果有默认结果，先给默认结果赋值
        if (!StringUtils.isEmpty(getDefaultResult())) {
            exeResultData = getDefaultResult();
        }

        // 是否命中
        boolean isHit = false;

        try {

            // 因为是表达式，所以执行结果必然是true 或者 false
            isHit = (boolean) compilableInstance.execute(varibleMap);
            log.info("exception = {},vars = {},isHit={}", getScriptData(), varibleMap, isHit);
            // 命中规则，则返回命中的返回变量
            if (isHit && !StringUtils.isEmpty(getResultData())) {
                exeResultData = getResultData();
            }

        } catch (ExpressionRuntimeException ex) {
            executionResponse.setExecuteStaus(CommonConstant.EXECUTE_RULE_FAIL);
            log.error("ExpressionRuntimeException = {},ruleName ={},varibleMap = {}", ex, getRuleName(), varibleMap);

        } catch (Throwable e) {
            executionResponse.setExecuteStaus(CommonConstant.EXECUTE_RULE_FAIL);
            log.error("expression Throwable = {},ruleName ={},varibleMap = {}", e, getRuleName(), varibleMap);

        }

        // 格式化返回变量
        Map<String, Object> exeResultMap = JSONObject.parseObject(exeResultData);

        // 返回是否命中
        executionResponse.setIsHit(isHit);
        // 返回命中结果
        executionResponse.setOutput(exeResultMap);
        return executionResponse;
    }

    @Override
    public String toString() {
        return "ExpressionRule{" +
                "rcRiskCodeCompiledInstance=" + rcRiskCodeCompiledInstance +
                '}';
    }
}
